package com.zw.cloud.tools.concurrent.thread.pool;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * CompletableFuture
 * https://mp.weixin.qq.com/s/L5RLrWTzEr_qVXoMQuYedg
 * 如果你不需要从回调函数中获取返回结果，可以使用 thenAccept() 或者 thenRun()。这两个方法的区别在于 thenRun() 不能访问异步计算的结果。
 *
 * thenCompose() 可以链接两个 CompletableFuture 对象，并将前一个任务的返回结果作为下一个任务的参数，它们之间存在着先后顺序。
 * thenCombine() 会在两个任务都执行完成后，把两个任务的结果合并。两个任务是并行执行的，它们之间并没有先后依赖顺序。
 * CompletableFuture 的 allOf()这个静态方法来并行运行多个 CompletableFuture 。allOf() 方法会等到所有的 CompletableFuture 都运行完成之后再返回
 *                                                                      anyOf() 方法不会等待所有的 CompletableFuture 都运行完成之后再返回，只要有一个执行完成即可！
 */
public class CompletableFutureTest {
    public static void main(String[] args) throws Exception{

        // 没有返回值 runAsync
        /*CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(()->{
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "runAsync == Void");
        });
        System.out.println(Thread.currentThread().getName());
        completableFuture.get();
        */
        // 有返回值 supplyAsync
        CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(()->{
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "supplyAsync == Integer");
            int i = 10 / 0;
            return 1024;
        });

        Integer result = completableFuture.whenComplete((t, u) -> {
            System.out.println("t == " + t);// 1024 返回结果
            System.out.println("u == " + u);// 错误信息 java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
        }).exceptionally((e) -> {
            System.out.println(e.getMessage()); // java.lang.ArithmeticException: / by zero
            return 500;
        }).get();
        System.out.println(result);
    }
}
